/**
*******************************************************
*@file  led.c
*@brief 对通用IO的定义、对SOC、RUN、ALARM的LED显示控制
*@author 花满楼
*@date     2020-7-1
*@version  V1
*@attention none
*@note none
*******************************************************
*/
#include "led.h"
#include "timer.h"
#include "delay.h"

/**
  * @brief  SOC百分比
  */
#define PERENT_00       0
#define PERENT_25       2500    ///<SOC=10% ，2位小数位，放大100倍
#define PERENT_50       5000
#define PERENT_75       7500
#define PERENT_100      10000


/**
  * @brief  pack综合状态
  */
typedef enum
{
    BE_READY      = 1,  ///<就绪状态
    BE_CHARGE     = 2,  ///<充电状态
    BE_DISCHARGE  = 3,  ///<放电状态
    BE_STATIC     = 4   ///<静置状态
} Sys_Status;

/**
*******************************************************
*@brief 初始化IO引脚
*@param   none
*@return  none
*@note    none
*******************************************************
*/
void Commin_IO_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOE_CLK_ENABLE();           //开启GPIOE时钟
	__HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟
    __HAL_RCC_GPIOD_CLK_ENABLE();           //开启GPIOD时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();           //开启GPIOB时钟
    __HAL_RCC_GPIOG_CLK_ENABLE();           //开启GPIOG时钟
    __HAL_RCC_GPIOH_CLK_ENABLE();           //开启GPIOH时钟
    __HAL_RCC_GPIOI_CLK_ENABLE();           //开启GPIOI时钟
    /************************SOC显示信号*************************/
    GPIO_Initure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_5; /*0~3是SOC显示*/
    GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;        //通用推挽输出
    GPIO_Initure.Pull = GPIO_PULLUP;                //上拉
    GPIO_Initure.Speed = GPIO_SPEED_FAST;           //快速
    HAL_GPIO_Init(GPIOD, &GPIO_Initure);
	/************************UART的控制信号*************************/
	GPIO_Initure.Pin = GPIO_PIN_8 | GPIO_PIN_9; //PD8：RE；PD9：DE
    GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  //复用推挽输出
    HAL_GPIO_Init(GPIOD, &GPIO_Initure);    //初始化PB11.10
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_RESET);    //PD8置1, 485接收数据
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_RESET);    //PD9置0, 485发送数据
    /************************运行和故障显示信号*************************/
    GPIO_Initure.Pin = GPIO_PIN_4 | GPIO_PIN_5; /*4是RUN，5是ALARM*/
    HAL_GPIO_Init(GPIOD, &GPIO_Initure);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET);      /*运行灯默认点亮*/
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET);  /*故障灯默认不亮*/
	/************************看门狗复位信号*************************/
    GPIO_Initure.Pin = GPIO_PIN_4 | GPIO_PIN_6; /*GPIO4是电源信号；GPIO6硬件看门狗复位信号，窗口时间（728.6ms-1214.4ms）内下降沿复位*/
    HAL_GPIO_Init(GPIOC, &GPIO_Initure);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);      /*默认不复位*/
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);      /*默认不复位*/
    /****************************************输入信号****************************************/
    /************************拨码开关输入信号*************************/
    GPIO_Initure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 ; /*0~3是拨码开关的输入状态*/
    GPIO_Initure.Mode = GPIO_MODE_INPUT;                //通用输入
    GPIO_Initure.Pull = GPIO_PULLUP;                //上拉
    GPIO_Initure.Speed = GPIO_SPEED_FAST;           //快速
    HAL_GPIO_Init(GPIOE, &GPIO_Initure);
    /***********************继电器干接点控制信号（暂时未使用）************************/
    GPIO_Initure.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4;    /*干接点2、3、4*/
    HAL_GPIO_Init(GPIOG, &GPIO_Initure);
    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_RESET);  /*与默认相反*/
    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_RESET);  /*与默认相反*/
    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_4, GPIO_PIN_RESET);  /*与默认相反*/
    /***********************蜂鸣器控制信号***************************/
    GPIO_Initure.Pin = GPIO_PIN_7;
    HAL_GPIO_Init(GPIOI, &GPIO_Initure);
    HAL_GPIO_WritePin(GPIOI, GPIO_PIN_7, GPIO_PIN_RESET);   /*默认关闭蜂鸣器*/
    /****************************************输入信号****************************************/
    /**********************风机的反馈信号***********************/
    GPIO_Initure.Pin = GPIO_PIN_12;
    GPIO_Initure.Mode = GPIO_MODE_INPUT;    //输入
    GPIO_Initure.Pull = GPIO_NOPULL;        //无上下拉电阻
    GPIO_Initure.Speed = GPIO_SPEED_HIGH;   //高速
    HAL_GPIO_Init(GPIOB, &GPIO_Initure);
}

/**
*******************************************************
*@brief 对SOC显示的控制
*@param[in]   SOC:值传递，2位小数位，放大100倍
*@param[in]   SOC:值传递，2位小数位，放大100倍
*@return  none
*@note    具体策略参照SOC显示策略
*******************************************************
*/
void SOC_Display(u16 SOC, u8 pack_status)
{
    if (pack_status == BE_CHARGE)
    {
        if (SOC <= PERENT_25)
        {
            if (0 != timer_soc_1s)
            {
                LED_SOC0_25 = ~LED_SOC0_25; //灯信号翻转
                LED_SOC25_50 = 0;
                LED_SOC50_75 = 0;
                LED_SOC75_100 = 0;
                timer_soc_1s = 0;
            }
        }
        else
            if (SOC <= PERENT_50)
            {
                if (0 != timer_soc_1s)
                {
                    LED_SOC0_25 = 1;
                    LED_SOC25_50 = ~LED_SOC25_50; //灯信号翻转
                    LED_SOC50_75 = 0;
                    LED_SOC75_100 = 0;
                    timer_soc_1s = 0;
                }
            }
            else
                if (SOC <= PERENT_75)
                {
                    if (0 != timer_soc_1s)
                    {
                        LED_SOC0_25 = 1;
                        LED_SOC25_50 = 1;
                        LED_SOC50_75 = ~LED_SOC50_75; //灯信号翻转
                        LED_SOC75_100 = 0;
                        timer_soc_1s = 0;
                    }
                }
                else
                    if (SOC <= PERENT_100)
                    {
                        if (0 != timer_soc_1s)
                        {
                            LED_SOC0_25 = 1;
                            LED_SOC25_50 = 1;
                            LED_SOC50_75 = 1;
                            LED_SOC75_100 = ~LED_SOC75_100; //灯信号翻转
                            timer_soc_1s = 0;
                        }
                    }
    }
    else
        if (SOC == PERENT_00)
        {
            LED_SOC0_25 = 0; //全灭
            LED_SOC25_50 = 0;
            LED_SOC50_75 = 0;
            LED_SOC75_100 = 0;
        }
        else
            if (SOC <= PERENT_25)
            {
                LED_SOC0_25 = 1;
                LED_SOC25_50 = 0;
                LED_SOC50_75 = 0;
                LED_SOC75_100 = 0;
            }
            else
                if (SOC <= PERENT_50)
                {
                    LED_SOC0_25 = 1;
                    LED_SOC25_50 = 1;
                    LED_SOC50_75 = 0;
                    LED_SOC75_100 = 0;
                }
                else
                    if (SOC <= PERENT_75)
                    {
                        LED_SOC0_25 = 1;
                        LED_SOC25_50 = 1;
                        LED_SOC50_75 = 1;
                        LED_SOC75_100 = 0;
                    }
                    else
                        if (SOC <= PERENT_100)
                        {
                            LED_SOC0_25 = 1;
                            LED_SOC25_50 = 1;
                            LED_SOC50_75 = 1;
                            LED_SOC75_100 = 1;
                        }
}

/**
*******************************************************
*@brief 对故障和运行的LED显示的控制
*@param[in]   *pro:保护型故障
*@param[in]   *alr:告警型轻微故障
*@param[in]   *comm_fail：通讯中断
*@param[in]   pack_status：设备综合状态
*@return  none
*@note    具体逻辑参照运行控制策略
*******************************************************
*/
void RUN_ALR_LED(u16 *pro, u16 *alr, u8 *comm_fail, u8 pack_status)
{
    if (0 != *pro)
    {
        LED_ALARM = 1;      //故障灯常亮
    }
    else
        if (0 != *alr)
        {
            if (0 != timer_alr_2s)
            {
                LED_ALARM = ~LED_ALARM;     //2s的频率闪烁
            }
        }
        else
            if (0 != *comm_fail)
            {
                if (0 != timer_alr_0P75s)   //0.75s频率闪烁
                {
                    LED_ALARM = ~LED_ALARM;
                }
            }
            else
                LED_ALARM = 0;

    if (pack_status == BE_STATIC)
    {
        LED_RUN = 1;
    }
    else
    {
        if (0 != timer_run_1s)          //1s频率闪烁
        {
            LED_ALARM = ~LED_ALARM;
        }
    }
}
